package models; import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.*; import views.MainView; /** * The task scheduler class */ public class TaskScheduler { private static TaskScheduler instance; private long simulationTime; private long startTime = System.currentTimeMillis(); private int numberOfServers = 3; private int serverNumber = 0; private ArrayList<Server> servers = new ArrayList<>(); private ArrayList<Thread> runningServers = new ArrayList<>(); private ArrayList<Task> customersArrived = new ArrayList<>(); private int maxLoadPerServer; private Date peakHour = new Date(); private AtomicInteger currentCustomers = new AtomicInteger(0); private int peakHourCustomers; private long serverShutdownTime; private Server serverShutdown; private Thread threadServerShutdown; private TaskScheduler() { } /** * initialization */ public void start() { int i; Operations.setCustomerHistory(new ArrayBlockingQueue<Task>( (int) (simulationTime / TaskGenerator.getInstance().getMinArrivalInterval()))); for (i = 1; i <= numberOfServers; i++) { Server s = new Server("Queue " + ++serverNumber, maxLoadPerServer); servers.add(s); Thread t = new Thread(s); runningServers.add(t); t.start(); } serverShutdownTime = (long) (new Random().nextDouble() * (simulationTime) + startTime + 1); i = new Random().nextInt(numberOfServers); serverShutdown = servers.get(i); threadServerShutdown = runningServers.get(i); } public static TaskScheduler getInstance() { if (instance == null) { instance = new TaskScheduler(); } return instance; } public static void deleteInstance() { instance = null; } /** * get queue with least customers * * @return */ public Server getServerWithMinNumberOfTasks() { int min = maxLoadPerServer; Server minServer = null; for (Server s : servers) { int size = s.getTasks().size(); if (size < min) { min = size; minServer = s; } } return minServer; } /** * the task receiver -> delegates tasks to servers * * @param task */ public void receiveTask(Task task) { customersArrived.add(task); if (!(task.isRescheduled())) { MainView.getLogging().append(task.getName() + " has arrived at time " + String.format("%tT", new Date(System.currentTimeMillis())) + "\n"); Operations.getCustomerHistory().add(task); currentCustomers.getAndIncrement(); if (currentCustomers.get() > peakHourCustomers) { peakHourCustomers = currentCustomers.get(); peakHour = new Date(); } } Server s = getServerWithMinNumberOfTasks(); if (s != null && !(s.isShutdown())) { try { Task taskToBeAdded = customersArrived.get(0); MainView.getLogging().append(taskToBeAdded.getName() + " has entered " + s.getName() + " at time " + String.format("%tT", new Date(System.currentTimeMillis())) + "\n"); taskToBeAdded.setQueue(s); s.getTasks().put(taskToBeAdded); customersArrived.remove(0); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public long getSimulationTime() { return simulationTime; } public void setSimulationTime(long simulationTime) { this.simulationTime = simulationTime; } public long getStartTime() { return startTime; } public int getNumberOfServers() { return numberOfServers; } public void setNumberOfServers(int numberOfServers) { this.numberOfServers = numberOfServers; } public int getMaxLoadPerServer() { return maxLoadPerServer; } public void setMaxLoadPerServer(int maxLoadPerServer) { this.maxLoadPerServer = maxLoadPerServer; } public AtomicInteger getCurrentCustomers() { return currentCustomers; } public void setCurrentCustomers(AtomicInteger currentCustomers) { this.currentCustomers = currentCustomers; } public Date getPeakHour() { return peakHour; } public int getPeakHourCustomers() { return peakHourCustomers; } public ArrayList<Thread> getRunningServers() { return runningServers; } public ArrayList<Server> getServers() { return servers; } public long getServerShutdownTime() { return serverShutdownTime; } public Server getServerShutdown() { return serverShutdown; } public Thread getThreadServerShutdown() { return threadServerShutdown; } }